package com.bourse.dbfeeder.services.feeder;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;

import com.bourse.core.services.utils.IsinCodeFactory;
import com.bourse.core.utils.Cotation;
import com.bourse.core.utils.IndiceComposition;
import com.bourse.core.utils.IsinCode;
import com.bourse.dbfeeder.constants.IndiceConstants;


/**
 * <h5><b>Utilisation</b></h5>
 * 
 * <p>Récupérer archive de données historiques</p>
 * <p>Dézipper et configurer chemin d'accès dans fichier de configuration de l'application</p>
 * <p>Aller sur ABCBourse </p>
 * <p>Télecharger la composition des indices pour chacun des suivants: CAC40, SBF120, CAC All Tradable,
 * 	   CAC Small, CAC Mid 60, CAC Large 60, CAC Mid & Small </p>
 * <p>ATTENTION  au format => Action Bourse. </p>
 * 
 * @author Guen
 *
 */
public class HistoFileDataDownloadImpl implements DataLoaderService {

	private static final int AB_FORMAT_ISIN = 0;
	private static final int AB_FORMAT_DATE = 1;
	private static final int AB_FORMAT_OPEN = 2;
	private static final int AB_FORMAT_PH = 3;
	private static final int AB_FORMAT_PB = 4;
	private static final int AB_FORMAT_CLOSE = 5;
	private static final int AB_FORMAT_VOLUME = 6;	
	
	private String histoDirectoryPath;

	private static final Logger LOGGER = Logger
			.getLogger(HistoFileDataDownloadImpl.class);

	private static final DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
				.appendDayOfMonth(2).appendLiteral("/").appendMonthOfYear(2).appendLiteral("/")
				.appendYear(2, 2).toFormatter();

		
	/**
	 * Charge les cotation des répertoires "Indices" et "Cac All Tradable"	  
	 * 
	 */
	public Map<IsinCode, List<Cotation>> getCotations() {
		
		LOGGER.info("[HISTO LOADER] - Reading datas from "+histoDirectoryPath);
		
		Map<IsinCode, List<Cotation>> cotations = new HashMap<IsinCode, List<Cotation>>();
		
		File repertoires = new File(histoDirectoryPath);
		String [] repList = repertoires.list();

		for(String rep : repList){
			
			if(IndiceConstants.CAC_ALL_TRADABLE.getHistoDirName().equals(rep) || 
					IndiceConstants.INDICES.getHistoDirName().equals(rep)){
			
				String currentDirStr = histoDirectoryPath + File.separator + rep;
				File currentDir = new File(currentDirStr);
				File[] files = currentDir.listFiles();
				
				for(File file : files){
					LOGGER.info("[HISTO LOADER] - Getting datas from "+file.getPath());
					try{
					
						BufferedReader buf = new BufferedReader(new FileReader(file));
						String line = null;
						int nbLine  = 0; 
						
						while( (line = buf.readLine()) != null ){
							if(nbLine>0){
								String[] content = line.split(";");
								
								String isin = content[AB_FORMAT_ISIN];
								IsinCode isinCode = IsinCodeFactory.getInstance().getIsinCode(isin);
								String theDate = content[AB_FORMAT_DATE];
								try{
									DateTime dateTime = inputFormatter.parseDateTime(theDate);		
									dateTime = dateTime.plusYears(2000);
									DateMidnight date = dateTime.toDateMidnight();
									
									List<Cotation> cotationList = cotations.get(isinCode);
									if (cotationList==null) {
										cotationList = new ArrayList<Cotation>();
										cotations.put(isinCode, cotationList);
									}
									
									Cotation cotation = new Cotation();
									cotationList.add(cotation);
									cotation.setIsin(isinCode);
									cotation.setCours(Double.valueOf(content[AB_FORMAT_CLOSE]));
									cotation.setOuverture(Double.valueOf(content[AB_FORMAT_OPEN]));
									cotation.setPlusBas(Double.valueOf(content[AB_FORMAT_PB]));
									cotation.setPlusHaut(Double.valueOf(content[AB_FORMAT_PH]));
									cotation.setDate(date);
									cotation.setVolume(content[AB_FORMAT_VOLUME]);
							
									
								}catch(Exception e){
									LOGGER.warn("[HISTO LOADER] - "+e.getMessage()+" for isin: "+isin+ "in rep: "+rep);
								}
							}
							nbLine++;
						}						
						
					}catch(FileNotFoundException e){
						LOGGER.error("[HISTO LOADER] - "+ e.getMessage());
					}catch(IOException e ){
						LOGGER.error("[HISTO LOADER] - "+ e.getMessage());					
					}
					
				}
			
			}
		}
		
		
		return cotations;
	}

	
	/**
	 * Get index compositions.
	 * 
	 */
	public Map<IsinCode, List<IndiceComposition>> getIndexComposition() {
		
		Map<IsinCode, List<IndiceComposition>> indiceCompostions = new HashMap<IsinCode, List<IndiceComposition>>();
		

		File repertoires = new File(histoDirectoryPath);
		String [] repList = repertoires.list();

		for(String rep : repList){
			
			if (!IndiceConstants.INDICES.getHistoDirName().equals(rep)) {
								
				String currentDirStr = histoDirectoryPath + File.separator + rep;
				File currentDir = new File(currentDirStr);
				File[] files = currentDir.listFiles();
				
				IndiceConstants indice = IndiceConstants.fromHistoDirName(rep);
				// Only rep stored in IndiceConstants are processed
				if(indice!=null){
					String isinIndice = indice.getIsin();
					IsinCode isinIndiceCode = IsinCodeFactory.getInstance().getIsinCode(isinIndice);
					
					List<IndiceComposition> indiceCompoList = indiceCompostions.get(indice.getIsin());
					if(indiceCompoList==null){
						indiceCompoList=new ArrayList<IndiceComposition>();
						indiceCompostions.put(isinIndiceCode, indiceCompoList);
					}
					
					for(File file : files){
						LOGGER.info("[HISTO INDICE COMPO LOADER] - "+ indice.getName().toUpperCase() +" Getting datas from "+file.getName());
						try{
						
							BufferedReader buf = new BufferedReader(new FileReader(file));
							String line = null;
							int nbLine  = 0; 
							
							while( (line = buf.readLine()) != null ){
								if(nbLine>0){
									String[] content = line.split(";");
									
									String isin = content[AB_FORMAT_ISIN];
									IsinCode isinCode = IsinCodeFactory.getInstance().getIsinCode(isin);
									String theDate = content[AB_FORMAT_DATE];
									try{
										DateTime dateTime = inputFormatter.parseDateTime(theDate);	
										dateTime = dateTime.plusYears(2000);
										DateMidnight date = dateTime.toDateMidnight();									
										IndiceComposition indiceComposition = new IndiceComposition(isinIndiceCode,isinCode, date);
										indiceCompoList.add(indiceComposition);					
										
									}catch(Exception e){
										LOGGER.warn("[HISTO INDICE COMPO LOADER] - "+e.getMessage()+" for isin: "+isin+ "in rep: "+rep);
									}
								}
								nbLine++;
							}						
							
						}catch(FileNotFoundException e){
							LOGGER.error("[HISTO LOADER] - "+ e.getMessage());
						}catch(IOException e ){
							LOGGER.error("[HISTO LOADER] - "+ e.getMessage());					
						}					
					}	
				}
			}
		}		
		return indiceCompostions;
	}

	
	public void setHistoDirectoryPath(String path) {
		this.histoDirectoryPath = path;
	}

	
}
